

//
//  WkWebViewController.m
//  OC注入JS
//
//  Created by YYY on 2018/1/5.
//  Copyright © 2018年 YYY. All rights reserved.
//

#import "WkWebViewController.h"

#import "TestViewController.h"

#import <WebKit/WebKit.h>

//iOS7下用UIWebView，iOS8后用WKWebView。

@interface WkWebViewController () <WKUIDelegate,WKNavigationDelegate>

@property (nonatomic,strong)WKWebView *webView;

//进度条
@property (nonatomic, strong) UIProgressView *progress;

@end

@implementation WkWebViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    //加载浏览视图
    [self.view addSubview:self.webView];

    //加载进度
    [self.view addSubview:self.progress];

    // 添加KVO监听
    [self.webView addObserver:self
                   forKeyPath:@"loading"
                      options:NSKeyValueObservingOptionNew
                      context:nil];
    [self.webView addObserver:self
                   forKeyPath:@"title"
                      options:NSKeyValueObservingOptionNew
                      context:nil];
    [self.webView addObserver:self
                   forKeyPath:@"estimatedProgress"
                      options:NSKeyValueObservingOptionNew
                      context:nil];
    
    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://m.dianping.com/tuan/deal/5501525"]];
    [self.webView loadRequest:request];
}

- (WKWebView *)webView
{
    if (_webView == nil)
    {
        _webView = [[WKWebView alloc] initWithFrame:CGRectMake(0, 10, self.view.frame.size.width, self.view.frame.size.height-64)];
        _webView.navigationDelegate = self;
        //_webView.UIDelegate = self;
        _webView.scrollView.scrollsToTop = NO;
        _webView.backgroundColor = [UIColor whiteColor];
    }
    return _webView;
}

- (UIProgressView *)progress
{
    if (!_progress)
    {
        _progress.frame = CGRectMake(0, 64, [UIScreen mainScreen].bounds.size.width, 10);
        _progress.progressTintColor = [UIColor redColor];
        _progress.progress = 0;
    }
    return _progress;
}
#pragma mark - 监听进度
#pragma mark - KVO
- (void)observeValueForKeyPath:(NSString *)keyPath
                      ofObject:(id)object
                        change:(NSDictionary<NSString *,id> *)change
                       context:(void *)context {
    if ([keyPath isEqualToString:@"loading"])
    {
        NSLog(@"loading");
    }
    else if ([keyPath isEqualToString:@"title"])
    {
        self.title = self.webView.title;
    }
    else if ([keyPath isEqualToString:@"estimatedProgress"])
    {
        NSLog(@"progress: %f", self.webView.estimatedProgress);
        self.progress.progress = self.webView.estimatedProgress;
        
    }
    
    // 加载完成
    if (!self.webView.loading)
    {
        // 手动调用JS代码
        // 每次页面完成都弹出来，大家可以在测试时再打开
        NSString *js = @"callJsAlert()";
        [self.webView evaluateJavaScript:js completionHandler:^(id _Nullable response, NSError * _Nullable error)
        {
            NSLog(@"response: %@ error: %@", response, error);
            NSLog(@"call js alert by native");
        }];
        
        [UIView animateWithDuration:0.5 animations:^{
            self.progress.alpha = 0;
        }];
    }
}
// 计算wkWebView进度条
//- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
//
//    if (object == self.webView && [keyPath isEqualToString:@"estimatedProgress"]) {
//        CGFloat newprogress = [[change objectForKey:NSKeyValueChangeNewKey] doubleValue];
//        NSLog(@"进度 %f",newprogress);
//
//        if (newprogress != 1.000000) {
//            // 网页加载时就展示进度
//            self.progress.hidden = NO;
//            self.progress.progress = newprogress;
//            self.webView.frame = CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height);
//        } else {
//            // 网页加载完成就进度
//            self.progress.hidden = YES;
//        }
//    }
//}
// 记得取消监听
- (void)dealloc
{
    [self.webView removeObserver:self forKeyPath:@"loading"];
    [self.webView removeObserver:self forKeyPath:@"title"];
    [self.webView removeObserver:self forKeyPath:@"estimatedProgress"];
}

//在发送请求之前，决定是否跳转
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler
{
    NSLog(@"在发送请求之前，决定是否跳转 decidePolicyForNavigationAction");
    
    NSString *URLString = navigationAction.request.URL.absoluteString;
    //    NSLog(@"监测到的WKWebView上的请求 %@",URLString);
    
    NSRange range = [URLString rangeOfString:@"hm://"];
    if (range.length > 0) {
        
        // 控制器的跳转
        [self.navigationController pushViewController:[[TestViewController alloc] init] animated:YES];
        
        // 不允许跳转,即不加载这个链接对应的内容
        decisionHandler(WKNavigationActionPolicyCancel);
    } else {
        // 允许跳转,即加载这个链接对应的内容
        decisionHandler(WKNavigationActionPolicyAllow);
    }
}

//界面开始加载
- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation
{
     NSLog(@"页面开始加载时调用 didStartProvisionalNavigation");
}

//在收到响应后，决定是否跳转
- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler
{
    NSLog(@"在收到响应后，决定是否跳转 decidePolicyForNavigationResponse");
    // 允许跳转,即继续加载这个链接对应的内容
    decisionHandler(WKNavigationResponsePolicyAllow);
    
    // 不允许跳转,即不再继续加载这个链接对应的内容
    //    decisionHandler(WKNavigationResponsePolicyCancel);
}

//当内容开始返回时调用
- (void)webView:(WKWebView *)webView didCommitNavigation:(WKNavigation *)navigation
{
    NSLog(@"当内容开始返回时调用 didCommitNavigation");
}

//界面加载完成之后调用
- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation
{
    // 拼接JS的代码
    NSMutableString *JSStringM = [NSMutableString string];
    
    // 删除导航
    [JSStringM appendString:@"var headerTag = document.getElementsByTagName('header')[0];headerTag.parentNode.removeChild(headerTag);"];
    // 删除底部悬停按钮
    [JSStringM appendString:@"var footerBtnTag = document.getElementsByClassName('footer-btn-fix')[0]; footerBtnTag.parentNode.removeChild(footerBtnTag);"];
    // 删除底部布局
    [JSStringM appendString:@"var footerTag = document.getElementsByClassName('footer')[0]; footerTag.parentNode.removeChild(footerTag);"];

    // 给标签添加点击事件
    [JSStringM appendString:@"var figureTag = document.getElementsByTagName('figure')[0].children[0]; figureTag.onclick = function(){window.location.href = 'hm://?src='+this.src};"];
    
    //    [JSStringM appendString:@"var figureTag = document.getElementsByTagName('figure')[0].children[0]; figureTag.onclick = function(){window.location.href = 'headerimageclick://www.yaowoya.com};"];
    
    // OC调用JS代码
    [self.webView evaluateJavaScript:JSStringM completionHandler:nil];
}

//界面加载失败时调用
- (void)webView:(WKWebView *)webView didFailNavigation:(WKNavigation *)navigation withError:(NSError *)error
{
    NSLog(@"页面加载失败时调用 didFailProvisionalNavigation");
}

////页面跳转的代理方法
////接收到服务器跳转请求之后调用
//- (void)webView:(WKWebView *)webView didReceiveServerRedirectForProvisionalNavigation:(WKNavigation *)navigation
//{
//
//}
//

#pragma mark - WKUIDelegate
- (void)webViewDidClose:(WKWebView *)webView {
    NSLog(@"%s", __FUNCTION__);
}

// 在JS端调用alert函数时，会触发此代理方法。
// JS端调用alert时所传的数据可以通过message拿到
// 在原生得到结果后，需要回调JS，是通过completionHandler回调
- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler {
    NSLog(@"%s", __FUNCTION__);
    UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"alert" message:@"JS调用alert" preferredStyle:UIAlertControllerStyleAlert];
    [alert addAction:[UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        completionHandler();
    }]];
    
    [self presentViewController:alert animated:YES completion:NULL];
    NSLog(@"%@", message);
}

// JS端调用confirm函数时，会触发此方法
// 通过message可以拿到JS端所传的数据
// 在iOS端显示原生alert得到YES/NO后
// 通过completionHandler回调给JS端
- (void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL result))completionHandler {
    NSLog(@"%s", __FUNCTION__);
    
    UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"confirm" message:@"JS调用confirm" preferredStyle:UIAlertControllerStyleAlert];
    [alert addAction:[UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        completionHandler(YES);
    }]];
    [alert addAction:[UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
        completionHandler(NO);
    }]];
    [self presentViewController:alert animated:YES completion:NULL];
    NSLog(@"%@", message);
}


// JS端调用prompt函数时，会触发此方法
// 要求输入一段文本
// 在原生输入得到文本内容后，通过completionHandler回调给JS
- (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString * _Nullable))completionHandler
{
    NSLog(@"%s", __FUNCTION__);
    
    NSLog(@"prompt = %@", prompt);
    UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"textinput" message:@"JS调用输入框" preferredStyle:UIAlertControllerStyleAlert];
    [alert addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {
        textField.textColor = [UIColor redColor];
    }];
    
    [alert addAction:[UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        completionHandler([[alert.textFields lastObject] text]);
    }]];
    [self presentViewController:alert animated:YES completion:NULL];}

@end
